package heap

import "unicode/utf16"

//字符串池
var internedStrings = map[string]*Object{}


// go字符串 转化为 java.lang.String
func JString(loader *ClassLoader, goStr string) *Object {
    //如果字符串已经在池中，直接返回
    if internedStr, ok := internedStrings[goStr]; ok {
        return internedStr
    }

    //转化为UTF16编码，创建java字符串实例
    chars := stringToUtf16(goStr)
    jChars := &Object{loader.LoadClass("[C"), chars, nil}

    jStr := loader.LoadClass("java/lang/String").NewObject()
    jStr.SetRefVar("value", "[C", jChars)

    //新创建的字符串放入字符串池中
    internedStrings[goStr] = jStr
    return jStr
}

// java.lang.String 转化为 go字符串
func GoString(jStr *Object) string {
    charArr := jStr.GetRefVar("value", "[C")
    return utf16ToString(charArr.Chars())
}

//go语言的string是utf8编码，Java的String是utf16编码，需要相互转换
// utf8 -> utf16
func stringToUtf16(s string) []uint16 {
    runes := []rune(s)         // utf32
    return utf16.Encode(runes) // func Encode(s []rune) []uint16
}

// utf16 -> utf8
func utf16ToString(s []uint16) string {
    runes := utf16.Decode(s) // func Decode(s []uint16) []rune
    return string(runes)
}

// todo
func InternString(jStr *Object) *Object {
    goStr := GoString(jStr)
    if internedStr, ok := internedStrings[goStr]; ok {
        return internedStr
    }

    internedStrings[goStr] = jStr
    return jStr
}
